/*
 * Cloud9: A MapReduce Library for Hadoop
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package apweb;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Random;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.lib.IdentityReducer;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apache.log4j.Logger;

/**
 * <p>
 * gernate a random data, output, key:number, value:number
 * </p>
 * 
 * <ul>
 * <li>[input-path] input path</li>
 * <li>[output-path] output path</li>
 * <li>[num-reducers] number of reducers</li>
 * </ul>
 * 
 * @author Jimmy Lin
 */
public class GenerateRandomData extends Configured implements Tool {
	private static final Logger sLogger = Logger.getLogger(GenerateRandomData.class);

	// mapper: emits (token, 1) for every word occurrence
	private static class MyMapper extends Mapper<LongWritable, Text, Text, Text> {

		// reuse objects to save overhead of object creation
		Random randomGenerator = new Random();
		
		@Override
		public void map(LongWritable key, Text value, Context context) throws IOException,
				InterruptedException {
			Configuration conf = context.getConfiguration();
			double resultNumber = Double.valueOf(conf.get("resultNumber"));
			int maxNumber = conf.getInt("maxNumber", 100000);
			int reducerNumber = conf.getInt("reduceTasks", 20);
			String tag = conf.get("tag");
			

			for(int i=0; i < resultNumber/reducerNumber; i++)
			{
				int tmpkey = randomGenerator.nextInt(maxNumber);
				String tmpvalue = randomGenerator.nextInt(maxNumber)
					+"\t"+randomGenerator.nextInt(maxNumber)
					+"\t"+randomGenerator.nextInt(maxNumber)
					+"\t"+tag;
				context.write(new Text(String.valueOf(tmpkey)), new Text(tmpvalue));
			}
			return;
			
		}
	}

	

	/**
	 * Creates an instance of this tool.
	 */
	public GenerateRandomData() {
	}

	private static int printUsage() {
		System.out.println("usage: [input-path] [output-path] [maxNumber] [result size] [num-reducers] [tag]");
		ToolRunner.printGenericCommandUsage(System.out);
		return -1;
	}

	/**
	 * Runs this tool.
	 */
	public int run(String[] args) throws Exception {
		if (args.length != 6) {
			printUsage();
			return -1;
		}

		String inputPath = args[0];
		String outputPath = args[1];
		int maxNumber = Integer.parseInt(args[2]);
		String resultNumber = args[3];
		int reduceTasks = Integer.parseInt(args[4]);
		String tag = args[5];

		sLogger.info("Tool: DemoWordCount");
		sLogger.info(" - input path: " + inputPath);
		sLogger.info(" - output path: " + outputPath);
		sLogger.info(" - max number: " + maxNumber);
		sLogger.info(" - number of results: " + resultNumber);
		sLogger.info(" - number of reducer: " + reduceTasks);
		sLogger.info(" - tag name: " + tag);

		Configuration conf = new Configuration();
		conf.set("resultNumber", resultNumber);
		conf.setInt("maxNumber", maxNumber);
		conf.setInt("reduceTasks", reduceTasks);
		conf.setStrings("tag", tag);
		
		Job job = new Job(conf, "GenerateRandomeData");
		job.setJarByClass(GenerateRandomData.class);

//		job.setNumReduceTasks(reduceTasks);
		job.setNumReduceTasks(0);

		FileInputFormat.setInputPaths(job, new Path(inputPath));
		FileOutputFormat.setOutputPath(job, new Path(outputPath));

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);

		job.setMapperClass(MyMapper.class);
//		job.setReducerClass(IdentityReducer.class);
//		job.setCombinerClass(MyReducer.class);
//		job.setReducerClass(MyReducer.class);

		// Delete the output directory if it exists already
		Path outputDir = new Path(outputPath);
		FileSystem.get(conf).delete(outputDir, true);

		long startTime = System.currentTimeMillis();
		job.waitForCompletion(true);
		sLogger.info("Job Finished in " + (System.currentTimeMillis() - startTime) / 1000.0
				+ " seconds");

		return 0;
	}

	/**
	 * Dispatches command-line arguments to the tool via the
	 * <code>ToolRunner</code>.
	 */
	public static void main(String[] args) throws Exception {
		int res = ToolRunner.run(new Configuration(), new GenerateRandomData(), args);
		System.exit(res);
	}
}
